<?php

namespace App\Http\Controllers\OpenShop\SiteLocation;

use App\Enums\OpenShop\InvestmentPromotion\SiteLocationEnum;
use App\Http\Controllers\BaseController;
use App\Http\Middleware\OpenShop\AppletAuth;
use App\Http\Validate\OpenShop\SiteLocation\CustomerAnalysisValidate;
use App\Http\Validate\OpenShop\SiteLocation\ProductAnalysisValidate;
use App\Http\Validate\OpenShop\SiteLocation\SiteFormValidate;
use App\Models\Common\ConfigModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopSignOrderModel;
use App\Models\OpenShop\SiteLocation\OpenShopSiteLocationExamineLogModel;
use App\Models\OpenShop\SiteLocation\OpenShopSiteLocationModel;
use App\Service\OpenShop\Feishu\PermissionService;
use App\Service\OpenShop\Feishu\SelectionService;
use App\Service\OpenShop\SiteLocation\AuthService;
use App\Service\OpenShop\SiteLocation\SiteLocationAttachService;
use App\Service\OpenShop\SiteLocation\SiteLocationAuditService;
use App\Service\OpenShop\SiteLocation\SiteLocationInputService;
use App\Service\OpenShop\SiteLocation\SiteLocationMallService;
use App\Service\OpenShop\SiteLocation\SiteLocationService;
use App\Models\OpenShop\SiteLocation\OpenShopSiteLocationProductAnalysisModel as ProductModel;
use App\Service\WaiMai\WaiMaiAnalysisBuildService;
use App\Service\WaiMai\WaiMaiAnalysisService;
use App\Support\FeishuMsgSupport;
use Carbon\Carbon;
use Exception;
use GuzzleHttp\Exception\GuzzleException;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
use Illuminate\Validation\ValidationException;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;

class SiteFormController extends BaseController
{

    public function setCustomerAnalysis(Request $request, $id)
    {
        $customerParams = CustomerAnalysisValidate::handelData($request->all());
        $authUser       = AuthService::getRmsUserInfo($request);
        SiteLocationService::setCustomerAnalysis($customerParams, $authUser, $id);
        $siteForm = SiteLocationService::getSiteForm($id, $authUser, 'customers');
        return $this->success($siteForm);
    }

    public function setProductAnalysis(Request $request, $id)
    {
        $productParams = ProductAnalysisValidate::handelData($request->all());
        $type          = $request->type ?? ProductModel::TYPE_1;
        $authUser      = AuthService::getRmsUserInfo($request);
        SiteLocationService::setProductAnalysis($productParams, $authUser, $id);
        $field    = $type == ProductModel::TYPE_1 ? ProductModel::CN_TYPE_1 : ProductModel::CN_TYPE_2;
        $siteForm = SiteLocationService::getSiteForm($id, $authUser, $field);
        return $this->success($siteForm);
    }

    public function setSiteForm(Request $request, $id)
    {
        $params   = $request->all();
        $authUser = AuthService::getRmsUserInfo($request);
        SiteLocationService::setSiteForm($id, $params, $authUser);
        return $this->success();
    }


    public function getSiteForm(Request $request, $id)
    {
        $siteLocationServer = new SiteLocationService();
        $field              = $request->get('field');
        $authUser           = AuthService::getRmsUserInfo($request);
        $siteForm           = $siteLocationServer->getSiteForm($id, $authUser, $field);
        return $this->success($siteForm);
    }


    public function getLeaseContractForm(Request $request, $id)
    {
        $siteLocationServer = new SiteLocationService();
        $authUser           = AuthService::getRmsUserInfo($request);
        $leaseContractFor   = $siteLocationServer->getLeaseContractForm($id, $authUser);
        return $this->success($leaseContractFor);
    }



    public function leaseContractSubmit(Request $request, $id)
    {
        (new SiteLocationService())->leaseSubmit($id);
        return $this->success();
    }

    public function audit(Request $request): JsonResponse
    {
        $orderNo     = $request->get('orderNo');
        $content     = $request->get('content');
        $isToStore   = $request->get('isToStore');
        $shopPattern = (int)$request->get('shopPattern');
        $patternType = (string)$request->get('patternType');
        $status      = $request->get('status');
        $authUser    = AuthService::getRmsUserInfo($request);
        $rmsUserId   = $authUser['userId'] ?? 0;
        $rmsUserName = $authUser["username"] ?? "";

        // 新售卖品类 取rms门店属性配置
        $sellingCategory = (string)$request->get('sellingCategory', '');

        // 修改门店模型
        SiteLocationService::updateShopPattern($orderNo, 0, [], false, 0, '', explode(',', $sellingCategory));

        (new SiteLocationAuditService())->audit($orderNo, $content, $status, $rmsUserId, $rmsUserName, $isToStore);

        return $this->success();
    }

    /**
     * 选址概览
     * @param Request $request
     * @return JsonResponse
     */
    public function countFormStatusNumber(Request $request): JsonResponse
    {
        $authInfo = AuthService::getRmsUserInfo($request);
        $city     = $request->get('city', '');
        $power    = (new \App\Service\OpenShop\SiteLocation\PermissionService())->orderLists($authInfo['userId']);
        $count    = SiteLocationService::countFormStatusNumber($city, $power);
        return $this->success($count);
    }

    public function getSiteSurveyInfo(Request $request)
    {
        $authInfo = AuthService::getRmsUserInfo($request);
        $this->validate($request, [
            'orderNo' => 'required|string'
        ]);
        $power          = (new \App\Service\OpenShop\SiteLocation\PermissionService())->orderLists($authInfo['userId']);
        try {
            //更新附近预占点位
            (new SiteLocationInputService($request->orderNo))->updateNearbyPlaceHolder();
        } catch (\Exception $exception) {

        }
        $siteSurveyInfo = SiteLocationService::getSiteSurveyInfo($request->orderNo, $authInfo, $power);
        return $this->success($siteSurveyInfo);
    }

    public function getSiteSurveyList(Request $request)
    {
        //根据类型去分配加盟商姓名或店铺编号
        $shopCode = '';
        $name     = '';
        $number   = '';
        $input    = $request->get('input', '');
        if (mb_strlen($input)) {
            if (is_numeric($input)) {
                $shopCode = $input;
                $number   = $input;
            } elseif (str_contains(strtoupper($input), "FY")) {
                $number = $input;
            } else {
                $name = $input;
            }
        }
        $status               = $request->get('status', '');
        $source               = $request->get('source', '');
        $handle               = $request->get('handle', '');
        $filterType           = $request->get('filterType', '');
        $filterValue          = $request->get('filterValue', '');
        $pageNum              = (int)$request->get('pageNum', 1);
        $pageSize             = (int)$request->get('pageSize', 10);
        $developConsultantIds = (string)$request->get("developConsultantIds", "");

        $authInfo = AuthService::getRmsUserInfo($request);
        $power    = (new \App\Service\OpenShop\SiteLocation\PermissionService())->orderLists($authInfo['userId']);
        $list     = SiteLocationService::getSiteSurveyList(
            $number, $name, $shopCode, $source,
            $status, $filterType, $filterValue, $pageNum, $pageSize, $power, $handle, $authInfo['userId'], $developConsultantIds
        );
        return $this->success($list);
    }


    /**
     * 提交表单验证
     * @param Request $request
     * @param $siteId
     * @return JsonResponse
     * @throws GuzzleException
     */
    public function checkFormRequired(Request $request, $siteId)
    {
        $authUser    = AuthService::getRmsUserInfo($request);
        $rmsUserId   = $authUser['userId'] ?? 0;
        $rmsUserName = $authUser["username"] ?? "";
        return $this->success(SiteLocationService::checkFormRequired($siteId, $rmsUserId, $rmsUserName));
    }

    /**
     * 软删除竞品信息
     * @param Request $request
     * @param $id
     */
    public function delProductAnalysis(Request $request, $id)
    {
        $authInfo = AuthService::getRmsUserInfo($request);
        SiteLocationService::delProductAnalysis($id, $authInfo);
        return $this->success();
    }

    /**
     * 房源线索添加
     *
     * @param Request $request
     * @return JsonResponse
     * @throws ValidationException
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     * @throws Exception
     * @throws GuzzleException
     */
    public function clueSiteLocationInsert(Request $request): JsonResponse
    {
        $params       = $request->all();
        $clueParams   = SiteFormValidate::clueSiteLocationInsertValidate($params);
        $attachParams = (object)SiteLocationService::getMapImage($clueParams);
        //$attachParams = SiteFormValidate::attachValidate($params);

        // 关联堪址任务ID
        $taskId = (int)$request->post('taskId', 0);

        $res = SiteLocationService::clueSiteLocationInsert(AppletAuth::$userInfo, $clueParams, $attachParams, $taskId);
        return $this->success($res);
    }

    /**
     * @throws NotFoundExceptionInterface
     * @throws ContainerExceptionInterface
     * @throws GuzzleException
     * @throws ValidationException
     */
    public function clueSiteLocationDetail(Request $request, int $id): JsonResponse
    {
        $authInfo   = AuthService::getRmsUserInfo($request);
        $clueParams = SiteFormValidate::clueSiteLocationDetailValidate($request->merge(["id" => $id])->all());
        $power      = (new \App\Service\OpenShop\SiteLocation\PermissionService())->orderLists($authInfo['userId']);
        return $this->success(SiteLocationService::getClueSiteLocationDetail($clueParams->id, $authInfo, $power));
    }

    /**
     * 所有房源详情
     *
     * @throws NotFoundExceptionInterface
     * @throws ContainerExceptionInterface
     * @throws ValidationException
     * @throws Exception
     */
    public function allClueDetail(Request $request, int $id): JsonResponse
    {
        $clueParams = SiteFormValidate::allClueDetailValidate($request->merge(["id" => $id])->all());
        return $this->success(SiteLocationService::allClueDetail($clueParams->id));
    }

    /**
     * @throws NotFoundExceptionInterface
     * @throws ContainerExceptionInterface
     * @throws ValidationException
     * @throws Exception
     */
    public function assignManager(Request $request, int $id): JsonResponse
    {
        $clueParams = SiteFormValidate::assignManagerValidate($request->merge(["id" => $id])->all());
        SiteLocationService::assignManager(AppletAuth::$userInfo, $id, $clueParams->managerId,
            $clueParams->managerName);
        return $this->success();
    }

    /**
     * @return JsonResponse
     * @throws GuzzleException
     */
    public function managerList(): JsonResponse
    {
        return $this->success(SiteLocationService::managerList());
    }

    /**
     * 房源时效
     *
     * @param Request $request
     * @param int $id
     * @return JsonResponse
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     * @throws ValidationException
     * @throws Exception
     */
    public function clueInvalid(Request $request, int $id): JsonResponse
    {
        //SiteFormValidate::clueInvalidValidate($request->merge(["id" => $id])->all());
        $this->validate($request, [
            'type' => 'required|int'
        ]);
        SiteLocationService::clueInvalid(AppletAuth::$userInfo, $id, $request->type);
        return $this->success();
    }

    /**
     * @param Request $request
     * @param int $id
     * @return JsonResponse
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     * @throws ValidationException
     * @throws Exception
     */
    public function clueUpDown(Request $request, int $id): JsonResponse
    {
        $clueParams = SiteFormValidate::clueUpDownValidate($request->merge(["id" => $id])->all());
        SiteLocationService::clueUpDown(AppletAuth::$userInfo, $id, $clueParams->type);
        return $this->success();
    }

    public function houseResourcesList(Request $request)
    {
        $type            = $request->get('type', 0);
        $filterValue     = $request->get('filterValue', '');
        $filterType      = $request->get('filterType', '');
        $status          = $request->get('status', '');
        $provinceCodeUse = $request->get('provinceCode', '');
        $chooses         = $request->get('chooses', '');
        $pageNum         = (int)$request->get('pageNum', 1);
        $pageSize        = (int)$request->get('pageSize', 10);
        $search          = (string)$request->get('search', '');
        $groupBy         = (int)$request->get('groupBy', 0);
        $grade           = $request->get('grade', '');
        $rent            = $request->get('rent', '');
        $area            = $request->get('area', '');
        $cUid            = (int)$request->get('cUid', 0);
        $power           = (new \App\Service\OpenShop\SiteLocation\PermissionService())->orderLists(AppletAuth::$userInfo->userId,
            \App\Service\OpenShop\SiteLocation\PermissionService::LIST_TYPE_HOUSE);
        $data            = SiteLocationService::houseClueList($type, $filterValue, $filterType,
            $status, $provinceCodeUse, $pageNum, $pageSize, $chooses, $search, $groupBy, $grade, $rent, $area, $power,
            AppletAuth::$userInfo->userId, $cUid);
        return $this->success($data);
    }

    public function houseResourcesCount(Request $request)
    {
        $scope       = PermissionService::dataPermission('openshop.sitelocation.siteform.houseresourceslist');
        $filterValue = $request->get('filterValue', '');
        $filterType  = $request->get('filterType', '');
        return $this->success(SiteLocationService::houseClueCount(AppletAuth::$userInfo, $scope, $filterValue,
            $filterType));
    }

    /**
     * @param Request $request
     * @return JsonResponse
     * @throws ValidationException
     */
    public function clueClassify(Request $request)
    {
        $this->validate($request, [
            'lng' => 'required',
            'lat' => 'required',
        ]);
        $lng = $request->get('lng', 0);
        $lat = $request->get('lat', 0);
        return $this->success(SiteLocationService::clueClassify($lng, $lat));
    }

    public function choosesClue(Request $request)
    {
        $this->validate($request, [
            'id'     => 'required|numeric',
            'clueId' => 'required|numeric',
        ]);
        $id     = $request->id;
        $clueId = $request->clueId;
        $newId  = SiteLocationService::choosesClue($id, $clueId);
        return $this->success(['id' => $newId]);
    }

    /**
     * 选址复盘
     * @param Request $request
     * @return JsonResponse
     * @throws ValidationException
     */
    public function replay(Request $request): JsonResponse
    {
        $this->validate($request, [
            'text'    => 'required|min:30|string',
            'orderNo' => 'required|string'
        ]);
        $authUser  = AuthService::getRmsUserInfo($request);
        $rmsUserId = $authUser['userId'] ?? 0;
        SiteLocationService::replay($rmsUserId, $request->orderNo, $request->text);
        return $this->success();
    }

    /**
     * 添加房源前置数据
     * @return JsonResponse
     * @throws ValidationException
     */
    public function baseHouseInfoByLatAndLng(Request $request)
    {
        $this->validate($request, [
            'lng' => 'required',
            'lat' => 'required',
        ]);
        $lng = $request->get('lng', 0);
        $lat = $request->get('lat', 0);
        return $this->success(SiteLocationService::getBaseHouseInfoByLatAndLng($lng, $lat));
    }


    /**
     * 房源筛选枚举
     * @return JsonResponse
     */
    public function houseSearchSift(): JsonResponse
    {
        return $this->success([
            'status'  => collect(OpenShopSiteLocationModel::CLUE_STATUS_MAP)->map(function ($text, $value) {
                return compact('text', 'value');
            })->values()->toArray(),
            'rent'    => collect(OpenShopSiteLocationModel::HOUSE_RENT_SIFT_MAPPING)->map(function ($text, $value) {
                return compact('text', 'value');
            })->values()->toArray(),
            'grade'   => collect(OpenShopSiteLocationModel::HOUSE_SHOP_GRADE_SIFT_MAPPING)->map(function (
                $text,
                $value
            ) {
                return compact('text', 'value');
            })->values()->toArray(),
            'groupBy' => collect(OpenShopSiteLocationModel::HOUSE_GROUP_BY_SIFT_MAPPING)->map(function ($text, $value) {
                return compact('text', 'value');
            })->values()->toArray(),
            'area'    => collect(OpenShopSiteLocationModel::HOUSE_AREA_SIFT_MAPPING)->map(function ($text, $value) {
                return compact('text', 'value');
            })->values()->toArray(),
        ]);
    }

    /**
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     * @throws ValidationException
     */
    public function updateClueBasisInfo(Request $request, $orderNo)
    {
        $params     = $request->all();
        $clueParams = SiteFormValidate::clueSiteLocationInsertValidate($params);
        SiteLocationService::updateClueBasisInfo(AppletAuth::$userInfo, $clueParams, $orderNo);
        return $this->success();
    }

    /**
     * 搜索商场
     * @param Request $request
     * @return JsonResponse
     * @throws GuzzleException
     */
    public function searchMall(Request $request): JsonResponse
    {
        $cityCode = $request->get('cityCode', 0);
        $mallName = $request->get('mallName', '');
        $lat      = (float)$request->get('lat', 0);
        $lng      = (float)$request->get('lng', 0);
        if (!$cityCode || !$lat || !$lng) {
            return $this->fail(10003, '参数无效');
        }
        return $this->success(SiteLocationMallService::getNearbyMall($cityCode, $mallName, $lat, $lng));
    }

    /**
     * 搜索街道
     * @param Request $request
     * @return JsonResponse
     */
    public function searchStreet(Request $request): JsonResponse
    {
        $cityCode   = $request->get('cityCode', 0);
        $streetName = $request->get('streetName', '');
        $lat        = (float)$request->get('lat', 0);
        $lng        = (float)$request->get('lng', 0);
        if (!$cityCode || !$lat || !$lng) {
            return $this->fail(10003, '参数无效');
        }
        return $this->success(SiteLocationMallService::getNearbyStreet($cityCode, $streetName, $lat, $lng));
    }


    public function businessRejectRestoreStep(Request $request)
    {

        $this->validate($request, [
            'orderNo' => 'required|string',
        ]);
        $orderNo = $request->get('orderNo', '');

        $siteLocationModel = OpenShopSiteLocationModel::query()
                                                      ->where("orderNo", $orderNo)
                                                      ->where("source", OpenShopSiteLocationModel::SOURCE_OPEN_SHOP)
                                                      ->first();

        //回退选址表状态
        OpenShopSiteLocationModel::query()->where("orderNo", $orderNo)->update([
            "status"              => SiteLocationEnum::STATUS_2,
            "siteStatus"          => OpenShopSiteLocationModel::SITE_STATUS_3,
            "houseEvaluateStatus" => SiteLocationEnum::HOUSE_EVALUATE_STATUS_WAIT
        ]);

        //历史审批日志软删
        OpenShopSiteLocationExamineLogModel::query()
                                           ->where("orderNo", $orderNo)
                                           ->where("type",
                                               OpenShopSiteLocationExamineLogModel::TYPE_DEFAULT)
                                           ->update(["isDeleted" => 1]);

        //更新商家驳回选址状态时间
        OpenShopSiteLocationExamineLogModel::query()
                                           ->where("orderNo", $orderNo)
                                           ->where("type",
                                               OpenShopSiteLocationExamineLogModel::TYPE_BUSINESS_CONFIRM_SITE_LOCATION)
                                           ->update(["isDeleted" => 0]);

        //发送重新选址消息给开发经理
        $signOrderMode = OpenShopSignOrderModel::query()->where("orderNo", $orderNo)->first();
        if ($siteLocationModel->developConsultantId > 0) {
            $msgSupport = FeishuMsgSupport::getInstance(
                "【选址审核驳回】{$signOrderMode->shopCode}夸父炸串（{$siteLocationModel->shopName}） 有新的选址评估审核完成，请注意",
                [$siteLocationModel->developConsultantId]
            );

            $msgSupport->setContent(
                ["name" => "房源所在区域", "value" => $siteLocationModel->cityArea],
                ["name" => "任务名称", "value" => "房源审核"],
                ["name" => "任务创建时间", "value" => formatDate(time())],
            )->msgSend(["path" => "pages/house-source/add-source?id={$siteLocationModel->id}"]);
        }

        return $this->success();
    }

    public function leaseReject(Request $request, $id)
    {
        $content = $request->post('content', '');
        SiteLocationService::leaseReject(AppletAuth::$userInfo, $id, $content);
        return $this->success();
    }

    /**
     * 门店合同通过
     * @param Request $request
     * @param $id
     * @return JsonResponse
     * @throws GuzzleException
     */
    public function leasePass(Request $request, $id): JsonResponse
    {
        SiteLocationService::leasePass(AppletAuth::$userInfo, $id);
        return $this->success();
    }

    public function heatMap(Request $request)
    {
        $this->validate($request, [
            'province'   => 'integer',
            'city'       => 'required|integer',
            'sourceType' => 'required|integer|between:3,4'
        ]);

        $province   = (int)$request->get('province', 0);
        $city       = (int)$request->get('city', 0);
        $sourceType = (int)$request->get('sourceType', 0);

        return $this->success(['fileUrl' => WaiMaiAnalysisBuildService::getCoordinateOssPath($province, $city, $sourceType, true, true)]);
    }


    /**
     * 转让房源操作
     * @param Request $request
     * @param $id
     * @return JsonResponse
     * @throws ValidationException
     */
    public function transferHouse(Request $request, $id): JsonResponse
    {
        $this->validate($request, [
            'managerId' => 'required|int',
        ]);

        $authUser  = AuthService::getRmsUserInfo($request); //userId

        SiteLocationService::transferHouse($authUser['userId'], $request->managerId, $id);

        return $this->success();
    }


    /**
     * 房源分公司列表--缓存
     * @param Request $request
     * @return JsonResponse
     * @throws ValidationException
     */
    public function clueClassifyCache(Request $request): JsonResponse
    {
        $this->validate(
            $request, [
            'lng' => 'required',
            'lat' => 'required',
        ]
        );
        $lng  = $request->get('lng', 0);
        $lat  = $request->get('lat', 0);
        $data = Cache::remember(
            'site:clueClassifyCache', 1200, function () use ($lng, $lat) {
            return SiteLocationService::clueClassify($lng, $lat);
        }
        );
        return $this->success($data);
    }


    /**
     * @param Request $request
     * @return JsonResponse
     */
    public function personal(Request $request): JsonResponse
    {
        $startTime = $request->get('startTime', Carbon::now()->startOfMonth()->format('Y-m-d'));
        $endTime   = $request->get('endTime', Carbon::now()->addMonth()->startOfMonth()->format('Y-m-d')); //与前端约定 取第二个月的第一天0点的时间
        $authUser  = AuthService::getRmsUserInfo($request); //Array
        return $this->success(SiteLocationAttachService::getPersonal($authUser, $startTime, $endTime));
    }


    /**
     * @param Request $request
     * @return JsonResponse
     * @throws ValidationException
     * @throws GuzzleException
     */
    public function siftList(Request $request): JsonResponse
    {
        $this->validate($request, [
            'source' => 'required',
            'key' => 'required',
        ]);
        $startTime = $request->get('startTime', Carbon::now()->startOfMonth()->format('Y-m-d'));
        $endTime   = $request->get('endTime', Carbon::now()->addMonth()->startOfMonth()->format('Y-m-d')); //与前端约定 取第二个月的第一天0点的时间
        $source    = $request->get('source');
        $key       = $request->get('key');
        $pageNum   = (int)$request->get('pageNum', 1);
        $pageSize  = (int)$request->get('pageSize', 10);
        $authUser  = AuthService::getRmsUserInfo($request); //Array
        return $this->success(SiteLocationAttachService::siftList($authUser, $startTime, $endTime, $source, $key, $pageNum, $pageSize));
    }


    public function nearbyTakeOut(Request $request)
    {
        $this->validate($request, [
            'orderNo' => 'required',
        ]);
        return $this->success(SiteLocationAttachService::nearbyTakeOut($request->orderNo));
    }


    /**
     * 保存热力图图片
     * @throws ValidationException
     */
    public function preserveHeatMap(Request $request): JsonResponse
    {
        $this->validate($request, [
            'orderNo' => 'required|string',
            'url'     => 'required'
        ]);
        SiteLocationAttachService::preserveHeatMap($request->orderNo, $request->url);
        return $this->success();
    }
}
